import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import ReportFormPeriodStatusMonitoring from '@main/entities/service/admin/reportForm/report-form-period-status-monitoring.entity';
import { Repository, IsNull, Between, In, LessThanOrEqual } from 'typeorm';
import { SysOperationLogService } from '../../system/operationLog/operationLog.service';
import BaseMachine from '@main/entities/service/admin/base/base-machine.entity';
import { format } from 'date-fns';

@Injectable()
export class ReportFormPeriodStatusMonitoringService {
  constructor(
    @InjectRepository(BaseMachine)
    private machineRepository: Repository<BaseMachine>,
    @InjectRepository(ReportFormPeriodStatusMonitoring)
    private reportFormPeriodStatusMonitoringRepository: Repository<ReportFormPeriodStatusMonitoring>,
    private operationLogService: SysOperationLogService
  ) {}

  /**
   * 罗列所有配置
   */
  async list(data) {
    const { entity = {} } = data;

    const { machineCodeList, dateStartTime, dateEndTime } = entity;

    const whereObj = {};

    if (machineCodeList && machineCodeList.length > 0) {
      whereObj['machineCode'] = In(machineCodeList);
    }

    const machineList: any = await this.machineRepository.find({
      where: whereObj,
    });

    await Promise.all(
      machineList.map(async (item) => {
        const { machineCode } = item;

        const where: any = [
          {
            machineCode,
            startTime: Between(new Date(dateStartTime).getTime(), new Date(dateEndTime).getTime()),
          },
          {
            machineCode,
            endTime: Between(new Date(dateStartTime).getTime(), new Date(dateEndTime).getTime()),
          },
        ];

        if (format(new Date(), 'yyyy-MM-dd') === dateStartTime.split(' ')[0]) {
          where.push({
            machineCode,
            startTime: LessThanOrEqual(new Date(dateStartTime).getTime()),
            endTime: IsNull(),
          });
        }

        item.list = await this.reportFormPeriodStatusMonitoringRepository.find({
          where,
          order: { updateTime: 'DESC' },
        });
      })
    );

    return machineList;
  }

  async add(data, user, mac, ip, syncHostSqlite) {
    const databaseOperationLogList = [];

    const { machineCode, machineStatus } = data;

    const obj = await this.reportFormPeriodStatusMonitoringRepository.findOne({
      where: { machineCode, machineStatus: machineStatus ? 0 : 1, endTime: IsNull() },
      order: { createTime: 'DESC' },
    });

    if (obj) {
      const { id } = obj;

      const endTime = new Date().getTime();

      await this.reportFormPeriodStatusMonitoringRepository.update({ id }, { endTime });

      databaseOperationLogList.push({
        type: 'update',
        dataType: 'obj',
        database: 'ReportFormPeriodStatusMonitoring',
        checkOnlyKeyList: [],
        data: { endTime },
        whereObj: { id },
        remark: `reportFormPeriodStatusMonitoring表更新更新设备状态记录`,
      });
    }

    const obj1 = await this.reportFormPeriodStatusMonitoringRepository.findOne({
      where: { machineCode, machineStatus: machineStatus ? 1 : 0, endTime: IsNull() },
      order: { createTime: 'DESC' },
    });

    if (!obj1) {
      const addData = {
        machineCode,
        machineStatus: machineStatus ? 1 : 0,
        startTime: new Date().getTime(),
      };

      await this.reportFormPeriodStatusMonitoringRepository.insert(addData);

      databaseOperationLogList.push({
        type: 'add',
        dataType: 'obj',
        database: 'ReportFormPeriodStatusMonitoring',
        checkOnlyKeyList: [],
        data: addData,
        whereObj: null,
        remark: `reportFormPeriodStatusMonitoring表行增设备状态记录`,
      });
    }

    if (databaseOperationLogList && databaseOperationLogList.length) {
      await this.operationLogService.add(
        {
          type: 'update',
          msg: `时段状态监控更新设备状态记录`,
          databaseOperationLogList,
          remark: `更新设备状态记录${data.machineCode}`,
          mac,
          ip,
          syncHostSqlite: isNaN(Number(syncHostSqlite)) ? 0 : Number(syncHostSqlite),
        },
        user
      );
    }
  }
}
